package com.fplanning.planner.business;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class WeightSlicer
{

    private int partitions = 10;
    private double maxValue = 100.0;
    private int numArrays = 3;

    public WeightSlicer(int partitions, double maxValue, int numArrays)
    {
        this.partitions = partitions;
        this.maxValue = maxValue;
        this.numArrays = numArrays;
    }

    public List<List<Double>> getCombos()
    {
        List<List<Double>> allArrays = new ArrayList<List<Double>>();
        for (int i = 0; i < numArrays; i++)
        {
            allArrays.add(new ArrayList<Double>());
        }

        getComboRecurser(0.0, 0, new ArrayList<Double>(), allArrays);
        return allArrays;
    }

    /**
     * Concept: - If you are a single column, the only valid value is MAX_VALUE
     * - If you have two columns, you step through all valid partition values,
     * and get the complementary sum
     * 
     * @param rowSumSoFar
     * @param listIndex
     * @param list
     */
    private void getComboRecurser(Double rowSumSoFar, int listIndex,
            List<Double> valuesSoFar, List<List<Double>> list)
    {
        if (listIndex >= list.size() - 1)
        {
            // this is the final index.. this is where we insert all values

            // Insert all previous values
            for (int i = 0; i < valuesSoFar.size(); i++)
            {
                list.get(i).add(valuesSoFar.get(i));
            }
            // Insert self.
            list.get(listIndex).add(maxValue - rowSumSoFar);
        }
        else
        {
            Double thisLoopValue = 0.0;
            for (int i = 0; i <= partitions; i++)
            {
                thisLoopValue = ((double) i)
                        * (maxValue / (double) partitions);
                if (thisLoopValue + rowSumSoFar > maxValue)
                {
                    break;
                }

                valuesSoFar.add(thisLoopValue);
                getComboRecurser(rowSumSoFar + thisLoopValue, listIndex + 1,
                        valuesSoFar, list);
                valuesSoFar.remove(thisLoopValue);
            }
        }
    }

    public static void main(String args[])
    {
        WeightSlicer slicer = new WeightSlicer(10, 100, 3);
        List<List<Double>> l = slicer.getCombos();
        for (int i = 0; i < l.get(0).size(); i++)
        {
            System.out.print(i + ": ");
            for (int j = 0; j < l.size(); j++)
            {
                System.out.print(l.get(j).get(i) + "\t");
            }
            System.out.println();
        }
    }
}
